package org.tri.gui.view;

import furbelow.SpinningDial;
import furbelow.WaitIndicator;
import java.awt.Font;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.ParseException;
import java.util.concurrent.ExecutionException;
import javax.swing.JOptionPane;
import javax.swing.text.DefaultFormatterFactory;
import org.tri.entity.Productor;
import org.tri.gui.MainFrame;
import org.tri.gui.worker.PersistenceListener;
import org.tri.gui.worker.ProductorPersistenceWorker;
import org.tri.gui.worker.ProductorTransientWorker;
import org.tri.gui.worker.TransientListener;
import org.tri.gui.worker.exceptions.ProductorDuplicadoException;
import org.tri.swing.AbstractEditableLabel;
import org.tri.swing.SwingUtils;

/*
 * El dialog {@code ProductorView} representa una vista para cualquier 
 * productor, permitiendo ver los detalles del mismo, asi tambié como 
 * modificar los datos y eliminar el productor si se desea.
 * @author kiira.
 * @version 1.0, Feb 3, 2012
 */
public class ProductorView extends javax.swing.JDialog implements
        PropertyChangeListener {

    /** Productor que esta vista representa. */
    private Productor productor;
    /** Bandera que indica si el productor es un productor persistido o nuevo. */
    private boolean productorNuevo;
    /** Resultado de las acciones realizadas sobre el productor en la vista.*/
    private int result;
    /** Bandera que indica si la vista se abrió para eliminar el productor. */
    private boolean toDelete;
    /** Icono de espera. */
    private SpinningDial loadingIcon;
    /** Componente para bloquear interaccion cuando se esta realizando una tarea. */
    private WaitIndicator waitIndicator;
    
    /**
     * Crea una nueva vista sobre el productor indicado.
     * @param parent frame padre de este dialog.
     * @param modal si la vista debe ser modal o no.
     * @param productor productor a ser representado por la vista
     */
    public ProductorView( java.awt.Frame parent, boolean modal,
                          Productor productor ) {
        super( parent, modal );
                
        initComponents();
        
        //alineamos el componente
        setLocationRelativeTo( parent );

        setProductor( productor );

        //asignamos el listener a los campos obligatorios para habilitar
        //deshabilitar el botón de guardar automáticamente
        eLTFRazonSocial.addPropertyChangeListener( 
                AbstractEditableLabel.MODIFIED_PROPERTY, this );
        eLFTFCUIT.addPropertyChangeListener( 
                AbstractEditableLabel.MODIFIED_PROPERTY, this );
        eLTFDomicilio.addPropertyChangeListener( 
                AbstractEditableLabel.MODIFIED_PROPERTY, this );
        eLTFLocalidad.addPropertyChangeListener(
                AbstractEditableLabel.MODIFIED_PROPERTY, this );
        eLFTFTelefono.addPropertyChangeListener(
                AbstractEditableLabel.MODIFIED_PROPERTY, this );
        eLTFTipoDoc.addPropertyChangeListener( 
                AbstractEditableLabel.MODIFIED_PROPERTY, this );
        eLFTFDocumento.addPropertyChangeListener( 
                AbstractEditableLabel.MODIFIED_PROPERTY, this );

        //inicializamos el icono de loading
        loadingIcon = new SpinningDial( 20, 20, 10 );

    }//end constructor

    /**
     * {@inheritDoc}
     */
    public ProductorView( java.awt.Frame parent, boolean modal ) {
        this( parent, modal, null );

    }//end constructor

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings ( "unchecked" )
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
        filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
        filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 10), new java.awt.Dimension(0, 10), new java.awt.Dimension(32767, 10));
        filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 10), new java.awt.Dimension(0, 10), new java.awt.Dimension(32767, 10));
        jPCentral = new javax.swing.JPanel();
        eLTFRazonSocial = new org.tri.swing.EditableLabelTF();
        jLDatosProductor = new javax.swing.JLabel();
        jLCUIT = new javax.swing.JLabel();
        eLFTFCUIT = new org.tri.swing.EditableLabelFTF();
        jLDomicilio = new javax.swing.JLabel();
        eLTFDomicilio = new org.tri.swing.EditableLabelTF();
        jLTelefono = new javax.swing.JLabel();
        eLFTFTelefono = new org.tri.swing.EditableLabelFTF();
        jLLocalidad = new javax.swing.JLabel();
        eLTFLocalidad = new org.tri.swing.EditableLabelTF();
        jLDatosResponsable = new javax.swing.JLabel();
        jLTipoDoc = new javax.swing.JLabel();
        eLTFTipoDoc = new org.tri.swing.EditableLabelTF();
        jLDocumento = new javax.swing.JLabel();
        eLFTFDocumento = new org.tri.swing.EditableLabelFTF();
        filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(150, 0), new java.awt.Dimension(150, 0), new java.awt.Dimension(150, 32767));
        filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(150, 0), new java.awt.Dimension(150, 0), new java.awt.Dimension(150, 32767));
        jBGuardar = new javax.swing.JButton();
        jBResetear = new javax.swing.JButton();
        jBEliminar = new javax.swing.JButton();
        jLWaitIcon = new javax.swing.JLabel();
        jBCerrar = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Detalles");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        getContentPane().add(filler3, java.awt.BorderLayout.WEST);
        getContentPane().add(filler4, java.awt.BorderLayout.EAST);
        getContentPane().add(filler5, java.awt.BorderLayout.NORTH);
        getContentPane().add(filler6, java.awt.BorderLayout.SOUTH);

        jPCentral.setLayout(new java.awt.GridBagLayout());

        eLTFRazonSocial.setDefaultValue( "Nombre y Apellido" );
        eLTFRazonSocial.setFont(org.tri.gui.view.ViewConstants.defaultLabelFont.deriveFont( Font.BOLD, 24 ));
        eLTFRazonSocial.setNextFocusableComponent(eLFTFCUIT);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 20, 0);
        jPCentral.add(eLTFRazonSocial, gridBagConstraints);
        eLTFRazonSocial.makeEditable( );

        jLDatosProductor.setFont(org.tri.gui.view.ViewConstants.underlinedLabelFont);
        jLDatosProductor.setText("Datos del Productor:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 10, 10);
        jPCentral.add(jLDatosProductor, gridBagConstraints);

        jLCUIT.setText("*CUIT:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 10);
        jPCentral.add(jLCUIT, gridBagConstraints);

        eLFTFCUIT.setNextFocusableComponent(eLTFDomicilio);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 15);
        jPCentral.add(eLFTFCUIT, gridBagConstraints);
        try{
            eLFTFCUIT.makeEditable( new DefaultFormatterFactory(new javax.swing.text.MaskFormatter("##-########-#")) );
        } catch(ParseException e){
            e.printStackTrace();
        }

        jLDomicilio.setText("*Domicilio:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 10);
        jPCentral.add(jLDomicilio, gridBagConstraints);

        eLTFDomicilio.setNextFocusableComponent(eLFTFTelefono);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 6;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
        jPCentral.add(eLTFDomicilio, gridBagConstraints);
        eLTFDomicilio.makeEditable( );

        jLTelefono.setText("Teléfono:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 10);
        jPCentral.add(jLTelefono, gridBagConstraints);

        eLFTFTelefono.setNextFocusableComponent(eLTFLocalidad);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 15);
        jPCentral.add(eLFTFTelefono, gridBagConstraints);
        eLFTFTelefono.makeEditable( new DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0"))) );

        jLLocalidad.setText("*Localidad:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 10);
        jPCentral.add(jLLocalidad, gridBagConstraints);

        eLTFLocalidad.setNextFocusableComponent(eLTFTipoDoc);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 6;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
        jPCentral.add(eLTFLocalidad, gridBagConstraints);
        eLTFLocalidad.makeEditable( );

        jLDatosResponsable.setFont(org.tri.gui.view.ViewConstants.underlinedLabelFont );
        jLDatosResponsable.setText("Datos del Responsable:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(15, 0, 10, 10);
        jPCentral.add(jLDatosResponsable, gridBagConstraints);

        jLTipoDoc.setText("Tipo de Doc.:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 10);
        jPCentral.add(jLTipoDoc, gridBagConstraints);

        eLTFTipoDoc.setNextFocusableComponent(eLFTFDocumento);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 15);
        jPCentral.add(eLTFTipoDoc, gridBagConstraints);
        eLTFTipoDoc.makeEditable( );

        jLDocumento.setText("Documento:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(3, 0, 3, 10);
        jPCentral.add(jLDocumento, gridBagConstraints);

        eLFTFDocumento.setNextFocusableComponent(eLTFRazonSocial);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 15);
        jPCentral.add(eLFTFDocumento, gridBagConstraints);
        eLFTFDocumento.makeEditable( new DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0"))) );
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 6;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPCentral.add(filler1, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 15);
        jPCentral.add(filler2, gridBagConstraints);

        jBGuardar.setText("Guardar");
        jBGuardar.setEnabled(false);
        jBGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jBGuardarActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(15, 0, 0, 0);
        jPCentral.add(jBGuardar, gridBagConstraints);

        jBResetear.setText("Resetear");
        jBResetear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jBResetearActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.insets = new java.awt.Insets(15, 5, 0, 5);
        jPCentral.add(jBResetear, gridBagConstraints);

        jBEliminar.setText("Eliminar");
        jBEliminar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jBEliminarActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.insets = new java.awt.Insets(15, 0, 0, 0);
        jPCentral.add(jBEliminar, gridBagConstraints);

        jLWaitIcon.setFocusable(false);
        jLWaitIcon.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
        jLWaitIcon.setIconTextGap(5);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(15, 15, 0, 0);
        jPCentral.add(jLWaitIcon, gridBagConstraints);

        jBCerrar.setText("Cerrar");
        jBCerrar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jBCerrarActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 7;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(15, 0, 0, 0);
        jPCentral.add(jBCerrar, gridBagConstraints);

        getContentPane().add(jPCentral, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jBCerrarActionPerformed( java.awt.event.ActionEvent evt ) {//GEN-FIRST:event_jBCerrarActionPerformed
        cerrarDialog();

    }//GEN-LAST:event_jBCerrarActionPerformed

    private void formWindowClosing( java.awt.event.WindowEvent evt ) {//GEN-FIRST:event_formWindowClosing
        cerrarDialog();

    }//GEN-LAST:event_formWindowClosing

    private void jBEliminarActionPerformed( java.awt.event.ActionEvent evt ) {//GEN-FIRST:event_jBEliminarActionPerformed
        //confirmamos antes de eliminar
        if ( JOptionPane.showConfirmDialog(
                this, String.format(
                "%s\n%s\n%s",
                "¿Esta seguro que desea eliminar el productor?",
                "Esta acción eliminará todos los datos relacionados con el",
                "mismo, incluyendo establecimientos asociados con sus"
              + " compras y ventas realizadas." ),
                "Confirmación",
                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE )
             == JOptionPane.YES_OPTION ) {
            //realizamos las tareas de gui para indicar que se raliza una 
            //transacción
            fireWaitTriggers( true );
            jLWaitIcon.setText( "Eliminando..." );

            //solicitamos al frame que evictee las transacciones actuales
            //si las mismas estan ligadas al productor
            MainFrame frame = ((MainFrame)getParent());
            
            if ( frame.getProductor() == productor ) 
                frame.evictCurrentTransactions();
            
            //en un thread aparte eliminamos el productor y lo quitamos 
            //de la tabla
            ProductorTransientWorker worker =
                                     new ProductorTransientWorker( productor );

            worker.addTransientListener( new ProductorTransientHandler() );

            worker.execute();

        }//end if

    }//GEN-LAST:event_jBEliminarActionPerformed

    private void jBResetearActionPerformed( java.awt.event.ActionEvent evt ) {//GEN-FIRST:event_jBResetearActionPerformed
        eLTFRazonSocial.resetToDefault();
        eLFTFCUIT.resetToDefault();
        eLTFDomicilio.resetToDefault();
        eLTFLocalidad.resetToDefault();
        eLFTFTelefono.resetToDefault();
        eLTFTipoDoc.resetToDefault();
        eLFTFDocumento.resetToDefault();

        jBGuardar.setEnabled( false );

    }//GEN-LAST:event_jBResetearActionPerformed

    private void jBGuardarActionPerformed( java.awt.event.ActionEvent evt ) {//GEN-FIRST:event_jBGuardarActionPerformed
        //realizamos las tareas previas de GUI
        fireWaitTriggers( true );
        jLWaitIcon.setText( "Guardando..." );
        
        //desactivamos el editmode de todos los labels
        eLTFRazonSocial.deactivateEditMode();
        eLFTFCUIT.deactivateEditMode();
        eLTFDomicilio.deactivateEditMode();
        eLTFLocalidad.deactivateEditMode();
        eLFTFTelefono.deactivateEditMode();
        eLTFTipoDoc.deactivateEditMode();
        eLFTFDocumento.deactivateEditMode();

        //seteamos las nuevas propiedades del productor
        productor.setRazonSocial( eLTFRazonSocial.getText() );
        long cuit = Productor.cuitAsLong( (String)eLFTFCUIT.getValue());
        productor.setDomicilio( eLTFDomicilio.getText() );
        productor.setLocalidad( eLTFLocalidad.getText() );

        if ( !eLFTFTelefono.getText().equals( "" ) )
            productor.setTelefono( Math.abs( (Long)eLFTFTelefono.getValue() ) );
        else
            productor.setTelefono( 0 );

        productor.setTipoDocumento( eLTFTipoDoc.getText() );

        if ( !eLFTFDocumento.getText().equals( "" ) )
            productor.setDocumento( 
                    Math.abs( (Long)eLFTFDocumento.getValue() ) );
        else
            productor.setDocumento( 0 );

        //en un thread aparte, guardamos el productor
        ProductorPersistenceWorker worker =
                                   new ProductorPersistenceWorker( productor,
                                                                   cuit );

        worker.addPersistenceListener( new ProductorPersistenceHandler() );

        worker.execute();
        
    }//GEN-LAST:event_jBGuardarActionPerformed

    private void formWindowOpened( java.awt.event.WindowEvent evt ) {//GEN-FIRST:event_formWindowOpened
        if ( toDelete )
            jBEliminar.doClick();
        
    }//GEN-LAST:event_formWindowOpened

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private org.tri.swing.EditableLabelFTF eLFTFCUIT;
    private org.tri.swing.EditableLabelFTF eLFTFDocumento;
    private org.tri.swing.EditableLabelFTF eLFTFTelefono;
    private org.tri.swing.EditableLabelTF eLTFDomicilio;
    private org.tri.swing.EditableLabelTF eLTFLocalidad;
    private org.tri.swing.EditableLabelTF eLTFRazonSocial;
    private org.tri.swing.EditableLabelTF eLTFTipoDoc;
    private javax.swing.Box.Filler filler1;
    private javax.swing.Box.Filler filler2;
    private javax.swing.Box.Filler filler3;
    private javax.swing.Box.Filler filler4;
    private javax.swing.Box.Filler filler5;
    private javax.swing.Box.Filler filler6;
    private javax.swing.JButton jBCerrar;
    private javax.swing.JButton jBEliminar;
    private javax.swing.JButton jBGuardar;
    private javax.swing.JButton jBResetear;
    private javax.swing.JLabel jLCUIT;
    private javax.swing.JLabel jLDatosProductor;
    private javax.swing.JLabel jLDatosResponsable;
    private javax.swing.JLabel jLDocumento;
    private javax.swing.JLabel jLDomicilio;
    private javax.swing.JLabel jLLocalidad;
    private javax.swing.JLabel jLTelefono;
    private javax.swing.JLabel jLTipoDoc;
    private javax.swing.JLabel jLWaitIcon;
    private javax.swing.JPanel jPCentral;
    // End of variables declaration//GEN-END:variables

    /**
     * Asignamos el productor a la vista. Solo puede ser asignado durante la
     * construcción del objeto o para reiniciar los campos luego de un commit
     * fallido, por eso es privado.
     * @param productor productor a asignar
     */
    private void setProductor( Productor productor ) {
        //si el productor es nulo, creamos uno nuevo
        //no se puede eliminar ya que no esta en la bd
        if ( productor == null ) {
            this.productor = new Productor();
            jBEliminar.setEnabled( false );
            productorNuevo = true;

        //caso contrario, asignamos los valores correspondientes a los campos
        } else {
            this.productor = productor;

            eLFTFCUIT.setDefaultValue( Productor.cuitAsString( productor.getCuit() ) );
            eLTFRazonSocial.setDefaultValue( productor.getRazonSocial() );
            eLTFDomicilio.setDefaultValue( productor.getDomicilio() );
            eLTFLocalidad.setDefaultValue( productor.getLocalidad() );
            eLFTFTelefono.setDefaultValue( productor.getTelefono() > 0
                                           ? String.valueOf( 
                                                       productor.getTelefono() )
                                           : "" );
            eLTFTipoDoc.setDefaultValue( productor.getTipoDocumento() );
            eLFTFDocumento.setDefaultValue( productor.getDocumento() > 0 
                                            ? String.valueOf(
                                                      productor.getDocumento() ) 
                                            : "" );

        }

    }//end método setProductor
    
    /**
     * Devuelve el productor asignado a esta vista.
     * @return productor asignado a la vista
     */
    public final Productor getProductor() {
        return productor;

    }//end método getProductor
    
    /**
     * Devuelve una constante de la clase {@code ViewConstansts} indicando en
     * que circunstancias se cerro la vista.
     * @return constante indicando el resultado de la vista.
     */
    public int getResult() {
        return result;

    }//end método getResult
    
    /**
     * Muestra la vista especificamente para eliminar el productor.
     */
    public void showToDelete() {
        toDelete = true;
        
        setVisible( true );
                
    }//end método showToDelete
    
    /**
     * Método auxiliar que cierra el dialog.
     */
    private void cerrarDialog() {
        //si no hay cambios válidos o el usuario no uqiere guardar los cambios,
        //cerramos el dialog
        if ( !jBGuardar.isEnabled() || askUndoChanges() ) {
            this.setVisible( false );
            this.dispose();
            
        }//end if

    }//end método cerrarDialog

    /**
     * Método auxiliar que se encarga de preguntar al usuario si desea
     * deshacer los cambios realizados en la vista.
     * @return <li>true si el usuario responde que si.<li>false si el usuario
     * responde que no.
     */
    private boolean askUndoChanges() {
        int option = JOptionPane.showConfirmDialog( 
                this,
                "Se realizaron cambios sobre el "
                + "productor,\nesta seguro que desea salir?",
                "¿Desea deshacer los cambios?",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.INFORMATION_MESSAGE );

        return option == JOptionPane.YES_OPTION;

    }//end método askUndoChanges
    
    /**
     * {@inheritDoc}
     */
    @Override
    public void propertyChange( PropertyChangeEvent evt ) {
        //comprueba que los campos obligatorios esten completados
        boolean readyToSave = eLTFRazonSocial.getText().length() > 0
                              && eLFTFCUIT.getText().length() > 0
                              && eLTFDomicilio.getText().length() > 0
                              && eLTFLocalidad.getText().length() > 0;
        
        //si el valor que se modificó en realidad esta en su valor por 
        //defecto, hay que comprobar si esto no generó que no haya ningún
        //cambio real en la vista
        if ( !(Boolean)evt.getNewValue() ) 
            readyToSave = readyToSave && 
                          (  eLTFRazonSocial.isModified() 
                          || eLFTFCUIT.isModified() 
                          || eLTFDomicilio.isModified()
                          || eLTFLocalidad.isModified() 
                          || eLFTFTelefono.isModified() 
                          || eLTFTipoDoc.isModified() 
                          || eLFTFDocumento.isModified() );
        
        //de acuerdo a las criterias evaluadas, habilitamos o no el boton 
        //guardar
        jBGuardar.setEnabled( readyToSave );

    }//end método propertyChange
    
    /**
     * Método auxiliar que lanza triggers gráficos para indicar al usuario
     * que se esta realizando una tarea que puede tardar cierto tiempo, durante
     * el cual el usuario no va a poder interactuar con la GUI.
     * @param inicio bandera que indica si se deben lanzar los triggers o 
     * cancelarlos.
     */
    private void fireWaitTriggers( boolean inicio ) {
        if ( inicio ) {
            jPCentral.requestFocus();
            waitIndicator = new WaitIndicator( jPCentral );
        } else
            waitIndicator.dispose();
        
        jBGuardar.setEnabled( inicio ? !inicio : inicio );
        
        jLWaitIcon.setEnabled( true );
        jLWaitIcon.setIcon( inicio ? loadingIcon : null );
        jLWaitIcon.setText( "" );

    }//end método fireWaitTriggers

    /**
     * Listener que realiza ciertas tareas luego de que se elimina el productor
     * asignado a la vista.
     */
    class ProductorTransientHandler implements TransientListener {

        /** Bandera que indica si ocurrio un error durante la eliminación. */
        private boolean error;

        /**
         * {@inheritDoc}
         */
        @Override
        public void doneTransit() {
            //quitamos los triggers graficos
            fireWaitTriggers( false );

            //si no ocurrio error, asignamos el result correspondiente y 
            //cerramos el dialog
            if ( !error ) {
                result = ViewConstants.DELETED;

                cerrarDialog();

            }

        }//end método doneTransit

        /**
         * {@inheritDoc}
         */
        @Override
        public void errorTransit( ExecutionException ex ) {
            error = true;

            dispose();
            ((MainFrame)getParent()).recoverFromFail();

        }//end método errorTransit

    }//end clase ProductorTransientHandler

    /**
     * Listener que se encarga de realizar algunas tareas posteriores a la
     * persistencia de un productor, ya sea nuevo o modificado.
     */
    class ProductorPersistenceHandler implements PersistenceListener {

        /** Bandera que indica si hubo un error durante la persistencia. */
        private boolean error;

        /**
         * {@inheritDoc}
         */
        @Override
        public void donePersisting() {
            //rehabilitamos la GUI
            fireWaitTriggers( false );

            //si no hubo error...
            if ( !error ) {
                if ( productorNuevo ) {
                    // y es un productor nuevo, asignamos el resultado 
                    //y cerramos la vista
                    result = ViewConstants.ADDED;

                    cerrarDialog();
                
                } else {
                    //y es un productor modificado, asignamos el resultado pero
                    //no cerramos la vista, simplemente modificamos los valores
                    //por defecto como si fuera una vista nueva
                    result = ViewConstants.MODIFIED;

                    setProductor( productor );
                    
                    jLWaitIcon.setText( "Guardado." );

                    SwingUtils.futureClearLabel( jLWaitIcon );

                }                
            //si hubo error-...
            } else {
                //"reiniciamos" el productor ya que no se pudo guardar
                
                //solo reiniciamos la mayoria de los campos si el 
                //establecimiento no es nuevo
                if ( !productorNuevo ) {
                    productor.setRazonSocial( 
                            eLTFRazonSocial.getDefaultValue() );
                    productor.setDomicilio( eLTFDomicilio.getDefaultValue() );
                    productor.setLocalidad( eLTFLocalidad.getDefaultValue() );
                    productor.setTipoDocumento( eLTFTipoDoc.getDefaultValue() );
                    
                    try {
                        productor.setCuit(
                                Long.parseLong( eLFTFCUIT.getDefaultValue() ) );
                    } catch ( NumberFormatException ex ) {
                        productor.setCuit( 0 );

                    }
                    
                    try {
                        productor.setTelefono(
                                Long.parseLong( 
                                eLFTFTelefono.getDefaultValue() ) );

                    } catch ( NumberFormatException ex ) {
                        productor.setTelefono( 0 );

                    }
                    
                    try {
                        productor.setDocumento(
                                Long.parseLong( eLFTFDocumento.getDefaultValue() ) );

                    } catch ( NumberFormatException ex ) {
                        productor.setDocumento( 0 );

                    }
                    
                } else //si el productor es nuevo, deshabilitamos el boton elim
                    jBEliminar.setEnabled( false );
                                
            }

        }//end método donePersisting

        /**
         * {@inheritDoc}
         */
        @Override
        public void errorPersisting( ExecutionException ex ) {
            error = true;

            if ( ex.getCause() instanceof ProductorDuplicadoException )
                JOptionPane.showMessageDialog( ProductorView.this,
                                               ex.getCause().getMessage(), 
                                               "Establecimiento Duplicado", 
                                               JOptionPane.INFORMATION_MESSAGE);
            else {
                dispose();
                ((MainFrame)getParent()).recoverFromFail();
                
            }
                

        }//end método errorPersisting       

    }//end clase ProductorPersistenceHandler

}//end clase ProductorView
